package xmw

import (
	"gitee.com/xiedongji/antgo/core"
	"gitee.com/xiedongji/antgo/cpts/xvalidate"
	"reflect"

	"github.com/gin-gonic/gin"
	en_locales "github.com/go-playground/locales/en"
	zh_locales "github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	en_translation "github.com/go-playground/validator/v10/translations/en"
	zh_translation "github.com/go-playground/validator/v10/translations/zh"
)

/* ================================================================================================ *
 * 功能:初始 化验证器 和 翻译器 (TranslationMiddleware)
 * 类型:中间件
 * 描述:https://github.com/go-playground/validator/blob/master/_examples/translations/main.go
 * ================================================================================================ */
func TranslationMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// 设置支持的本地化语言
		en := en_locales.New()
		zh := zh_locales.New()
		uni := ut.New(zh, zh, en) // 实例化 翻译器库(目前zh,en两种语言)

		validateInstance := validator.New() // 实例化 验证器

		// 根据参数 选择本地语言实例 获取翻译器
		locale := ctx.DefaultQuery("lan", "zh")
		translatorInstance, _ := uni.GetTranslator(locale) // 实例化 翻译器

		// 翻译器 注册到 validator
		switch locale {
		case "en":
			// 注册 英文 验证和 翻译器
			en_translation.RegisterDefaultTranslations(validateInstance, translatorInstance)
			// 加入 comment_en 标签
			validateInstance.RegisterTagNameFunc(func(field reflect.StructField) string {
				return field.Tag.Get("comment_en")
			})
			break
		default:
			// 注册 中文 验证 和 翻译器
			zh_translation.RegisterDefaultTranslations(validateInstance, translatorInstance)
			// 加入 comment 标签 对应 dto 中的 comments标签
			validateInstance.RegisterTagNameFunc(func(field reflect.StructField) string {
				return field.Tag.Get("comxent")
			})

			// 注入 自定义 验证器
			xvalidate.IValidateRule(validateInstance)

			// 注入 自定义 翻译器
			xvalidate.ITranslator(validateInstance, translatorInstance)

			break
		}

		// 设置翻译器 环境
		ctx.Set(core.CTX_VALIDATOR_KEY, validateInstance)
		ctx.Set(core.CTX_TRANSLATOR_KEY, translatorInstance)

		ctx.Next()
	}
}
